package hr.fer.apr.ht41337.lab4;

import java.util.TreeMap;

public class NumerickaIntegracija {

	private Matrica A, B;
	private double T;
	private boolean ispis = false;
	private int brojIteracija = 5;
	
	public NumerickaIntegracija (Matrica A, Matrica B, double T) {
		this.A = A;
		this.B = B;
		this.T = T;
	}
	
	public TreeMap<Double, Matrica> RungeKutta (Matrica x0, double tmax) throws Exception {
		TreeMap<Double, Matrica> izlaz = new TreeMap<Double, Matrica>();
		izlaz.put(0.0, x0);
		Matrica x = x0;

		for (int i = 1; i * T <= tmax; i++) {
			Matrica m1 = A.times(x).plus(B);
			Matrica m2 = A.times(x.plus(m1.times(T / 2))).plus(B);
			Matrica m3 = A.times(x.plus(m2.times(T / 2))).plus(B);
			Matrica m4 = A.times(x.plus(m3.times(T))).plus(B);
			x = x.plus(m1.plus(m2.times(2)).plus(m3.times(2)).plus(m4).times(T / 6));
			izlaz.put(i * T, x);
			if (ispis && i % brojIteracija == 1){
				System.out.println("iteracija " + i + ": " + 
						i * T + ", ");
				x.print();
			}
		}
		return izlaz;
	};
	
	public TreeMap<Double, Matrica> TrapezniPostupak (Matrica x0, double tmax) throws Exception {
		TreeMap<Double, Matrica> izlaz = new TreeMap<Double, Matrica>();
		izlaz.put(0.0, x0);
		Matrica x = x0;
		for (int i = 1; i * T <= tmax; i++) {
			Matrica temp = Matrica.jedinicna(A.rows).minus(A.times(T / 2));
			temp = temp.inverse();
			Matrica R = Matrica.jedinicna(A.rows).plus(A.times(T / 2));
			R = temp.times(R);
			Matrica S = B.times(T);
			S = temp.times(S);
			x = R.times(x).plus(S);
			izlaz.put(i * T, x);
			if (ispis && i % brojIteracija == 1){
				System.out.println("iteracija " + i + ": " + 
						i * T + ", ");
				x.print();
			}
		}
		return izlaz;
	}

	public void setIspis(boolean ispis) {
		this.ispis = ispis;
	}

	public void setBrojIteracija(int brojIteracija) {
		this.brojIteracija = brojIteracija;
	}

	
}
